Date : 8 ao�t 1991, 8 septembre 1991 ( fin )
Protection : MOT DE PASSE
Programme : SUPER.C
Outils : SOFT-ICE V2.50,
QUAID, MASM, LINK, EXE2BIN, ST.COM,
SOURCER, BIBLE PC, et j'en oublie...
Fichier : STO.COM ( personnel )
Temps pass� : 1 SEMAINE ( mise au point )
Soci�t� : KONAMI
Divers : Compact� par un compacteur maison
Origine : INDONESIE
Num�ro : 139
8 Ao�t 1991;
On trouve de suite le saut � modifier en 1465:008C mais la cha�ne qui
l'entoure n'appara�t pas dans le fichier, et ce dernier n'est ni
compact� par LZEXE ni EXEPACK ni PKLITE.
1465:0089 3B46E2
1465:008C 7422 JZ ... ; A REMPLACER PAR EB ( JMP )
1465:008E 8D
Donc la solution du d�tournement d'interruption s'impose
automatiquement mais malheureusement d�s que l'INT 21 ne pointe plus
sur son vecteur d'origine le SOFT le d�tecte et refuse de continuer en
disant qu'il ne dispose plus assez de m�moire. Ce qui est faux; j'ai
v�rifi� !
En fait n'importe quelle interruption d�tourn�e fait afficher le m�me
message. D'autres essais mettent en �vidence que SUPER_C ne supporte
pas trop les programmes r�sidents; il ne r�agit pas pour NC, MOUSE.COM,
et SOFT-ICE ( encore heureux ! ). Par contre il "jette" mes FRED.COM
ainsi que PERISCOPE et QUAID.
Peut-�tre que je ne lib�re pas assez de m�moire avec mes FREDs, mais
ils ne prennent qu'en moyenne 200 � 300 octets lorsqu'ils sont
r�sidents, alors quoi...?
Une ruse du programmeur ou un d�faut de mes FRED.COM ?
A voir...
Premi�re semaine de Septembre 1991;
Je d�cide d'examiner la "soluce" de STUNTS qui consiste �galement �
d�tourner l'INT 21 ( tiens on m'a copi� ! ) par contre l'auteur
qui n'est pas avare d'�loges et qui laisse volontairement tra�ner son
adresse dans presque tous les fichiers ( voir les infos.com de STUNTS )
proc�de avec une approche diff�rente.
Son programme commence � ne r�server que la m�moire utile n�cessaire,
puis il d�tourne l'INT 21 sous-fonction 1A ( set DTA ) sur un vecteur
personnel qui ira modifier le test de la protection du jeu. Apr�s cela
il charge le programme du jeu normalement par la fonction EXEC sous-
fonction 00 de l'INT 21. D�s que l'on quitte le jeu le contr�le est
rendu � son programme qui replace le vecteur de l'INT 21 sur sa valeur
d'origine et quitte le jeu par la fonction 4C de l'INT 21.
C'est plus �l�gant car cela �vite de faire un fichier BATCH qui appelle
FRED.COM puis le jeu, et rappelle FRED.COM pour qu'il se d�sinstalle.
Par contre si j'avais su ce qui m'attendait en me lan�ant dans ce mini-
projet ( qui n'a de mini que le nom ) je n'aurais jamais commenc�
d'autant plus qu'actuellement tout ne fonctionne pas encore comme il
faudrait; SUPER_C revient au DOS avec un message d'erreur du style:
ERROR XXXX, NULL ASSIGNEMENT POINTER.
Mais enfin la protection est "stripp�e" et le jeu ne se plante pas !
En bref; trois jours de "brain storming", d'essais en tout genre,
la bible PC feuillet�e du d�but � la fin ( pour m'apercevoir qu'il me
manquait malgr� tout des infos ), de plantages chroniques, en passant
par la correction du lanceur de STUNTS avec en prime la carte sonore
qui faisait �galement des siennes lorsqu'elle est d�clar�e en SOUND
BLASTER et qui fonctionne correctement lorsqu'on l'appelle ADLIB.
( c'est bien une SOUND BLASTER que j'ai ramen�e ? ).
Un point positif toutefois; j'ai appris une foule de choses sur le
fonctionnement des COM, EXE, OVL et TSR ainsi que sur la fonction 4B
qui n'est pas si simple � mettre en oeuvre...
Ci-dessous le lanceur du jeu STUNT corrig�....
Le segment SP �tait �cras� par le segment DS, une instruction
MOV BX,[BP+0A] �tait inutile puisque BX n'�tait pas utilis� dans
la routine de l'INT 21 d�tourn�e. Ce qui m'a permis d'enlever
�galement un PUSH BX et son POP. A ce moment malheureusement la
protection ne fonctionnait plus. En fait SP �tait charg� dans BP et
avec un PUSH en moins il a donc fallu corriger l'instruction suivante
MOV AX,[BP-0C] en MOV AX,[BP-0A] ! ouf.
Un autre probl�me du au fait que SOURCER dessassemble en pla�ant des
r�f�rences d'adresses dans les instructions au lieu d'�tiquettes m'a
plant� mon programme lorsque j'avais rajout� une DATA DW 0. En faisant
cela la r�f�rence du d�but de mon pointeur INT21 se trouvait d�caler
de +2.
data_11e equ 459Bh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
sto proc far
start: jmp loc_1
db 90h
nom_prg db 'STUNTS.COM',0,0,0 ; 12 car max + nul
paramet db 0, 0 ; Pour les d�tails voir la
ENVIR dw 0 ; bible PC ou moi-m�me...
data_3 dw 0
FCB_1 dw 0
data_5 dw 0
FCB_2 dw 0
data_7 dw 0
sauve_SP dw 0 ; Premi�re correction.
sauve_SS dw 0
data_9 dw 0, 0
loc_1: mov sauve_SP,sp ; On sauve SP et
mov sauve_SS,ss ; SS car la fonction EXEC les d�truit.
mov ah,4Ah
mov bx,2Fh
int 21h ; lib�re la m�moire, bx=nbr paragraphes
mov ax,80h
mov ENVIR,ax ; Ligne de commande.
mov data_3,ds
mov ax,5Ch ; Premier FCB.
mov FCB_1,ax
mov data_5,ds
mov ax,6Ch ; Second FCB.
mov FCB_2,ax
mov data_7,ds
mov ah,35h
mov al,21h
int 21h ; On r�cup�re le vecteur de l'INT 21
mov cs:data_9,bx
mov word ptr cs:data_9+2,es
mov ah,25h
mov al,21h
lea dx,cs:[int21] ; Load effective addr
int 21h ; l'INT 21 pointe sur un autre vecteur.
lea dx,cs:[nom_prg] ; Load effective addr
push ds
pop es
lea bx,cs:[paramet] ; Load effective addr
mov al,0
mov ah,4Bh
int 21h ; run progm @ds:dx, parm @es:bx
mov sp,sauve_SP
mov ss,sauve_SS
mov ah,25h
mov al,21h
mov dx,cs:data_9
mov ds,word ptr cs:data_9+2
int 21h ; on replace le vecteur d'origine.
mov ah,4Ch
int 21h ; on quitte.
sto endp
; int 21 d�tourn�e...
int_21h_entry proc far
int21: push ax
push ds
; push bx ; supprim�.
push bp
pushf ; Push flags
cmp ah,1Ah
jne loc_2 ; Jump if not equal
cmp dx,3FE4h
jne loc_2 ; Jump if not equal
mov bp,sp
; mov bx,[bp+0ah] ; deuxi�me correction.
mov ax,[bp+0ah] ; Modifi� ( d'origine + 0Ch )
sub ax,1DF1h
mov ds,ax
mov ax,ds:data_11e
cmp ax,775h
jne loc_2 ; Jump if not equal
mov word ptr ds:data_11e,9090h
loc_2: popf ; Pop flags
pop bp
; pop bx ; supprim�.
pop ds
pop ax
jmp dword ptr cs:data_9
int_21h_entry endp
seg_a ends
end start
Cette routine adapt�e � n'importe quel programme COM fonctionne
parfaitement ainsi que pour les programmes EXE de moins de 64k !
�a commence. Les programmes sup�rieurs � 64k se plante d�s que l'on
veut les quitter. Un programme compact� par LZ91 qui pr�sente une
taille inf�rieure � 64k se crache �galement mais c'est normal
puisqu'une foi d�compact� en m�moire il d�passe 64k.
La premi�re correction effectu�e ( sauvegarde correcte de SS:SP )
les programmes EXE reviennent au DOS normalement quelque soit leur
taille.
J'assemble une version pour SUPER_C sans d�tournement d'INT pour voir.
Le probl�me consiste � v�rifier si les param�tres de la ligne de
commande sont bien transmis de mon programme au programme de SUPER_C
et si celui-ci ne fait pas une allergie.
SUPER_C est lanc� comme suit: LOAD /U EGA 1, je lance donc mon programme
appel� STO avec les m�mes param�tres. Et cela fonctionne ! Je v�rifie
rapidement avec SOFT-ICE et effectivement je trouve bien au d�but de
l'adresse 0080h de mon STO la cha�ne LOAD /U EGA 1.
Le dernier essai avant de crier victoire est de d�tourner l'INT 21 et
de relancer. L'INT 21 est simplement d�tourn�e sans traitement.
Le jeu se charge toujours correctement. Cette fois-ci il ne suffit
plus que de patcher l'endroit du test de la protection.
C'est vite dit et je n'arrive pas � trouver mon segment IP qui comporte
mon saut 7422.
J'essaie une autre interruption que la 1A sans meilleur r�sultat.
Avec SOFT-ICE je vois que la routine est �crite en m�moire d�s le tout
d�but du chargement du programme, mais impossible de mettre la main
dessus par la suite que ce soit par l'interm�diaire de BP, ES, DX, ou
plus simplement SS. Je fais une recherche de 65536 octets sur chacun de
ces segments sans r�sultat. Je PUSHe et POPe SP de plus et moins 50 en
vain.
Pourtant lors de la demande du code la routine est bien l� quelque POP
plus hauts ! Le probl�me est que l'INTERRUPTION 21 n'est plus appel�e
dans la zone de demande du mot de passe.
Une solution radicale existe pourtant c'est de d�tourner l'INT 09 qui
elle se d�clenche d�s que l'on appuie sur une touche. ( il n'y a rien
de plus pr�s ! ) mais c'est une IT hard.
Dans le programme les caract�res sont demand�s par l'INT 16 sous-
fonction 01. Je la d�tourne pour voir et c'est tout vu; cela fonctionne.
Ci-dessous le programme en assembleur il ne reste plus qu'un probl�me
� r�soudre c'est d'�viter le message NUL POINTER ASSIGNEMENT.
; PATCH POUR LE PROGRAMME SUPER_C
; DETOURNEMENT DE L'INT 16 SOUS-FONCTION 01
adr_ip equ 8ch
seg_a segment byte public
assume cs:seg_a, ds:seg_a, es:seg_a, ss:seg_a
org 100h
sto proc far
start:
jmp init ; r�duire la m�moire et d�placer la
db 90h ; pile plus pr�s.
nom_prg db 'load.exe',0,0,0,0,0 ; 12 car max + nul
paramet dw 0 ; M�me bloc d'environnement.
ENVIR dw 0 ; Les param�tres de la ligne de
data_3 dw 0 ; commande sont recopi�s ici puis
FCB_1 dw 0 ; transmis au programme fils. ( 80h )
data_5 dw 0 ; "LOAD /U EGA 1"
FCB_2 dw 0
data_7 dw 0
sauve_SP dw 0
sauve_SS dw 0
data_9 dw 0, 0
drap equ 0
;------------------------------ PROGRAMME PERE ------------------------------
loc_1: mov sauve_SP,sp
mov sauve_SS,ss
mov ax,80h
mov ENVIR,ax ; Ligne de commande...
mov data_3,ds
mov ax,5Ch ; Premier FCB ( inutilis� )
mov FCB_1,ax
mov data_5,ds
mov ax,6Ch ; Second FCB ( inutilis� )
mov FCB_2,ax
mov data_7,ds
mov ah,35h
mov al,16h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov cs:data_9,bx
mov word ptr cs:data_9+2,es
mov ah,25h
mov al,16h
lea dx,cs:[int16] ; Load effective addr
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
lea dx,cs:[nom_prg] ; Load effective addr
push ds
pop es
lea bx,cs:[paramet] ; Load effective addr
mov al,0
mov ah,4Bh
int 21h ; Appel du programme fils.
; run progm @ds:dx, parm @es:bx
mov sp,sauve_SP
mov ss,sauve_SS
mov ah,25h
mov al,16h
mov dx,cs:data_9
mov ds,word ptr cs:data_9+2
int 21h ; set intrpt vector al to ds:dx
mov ah,4dh
int 21h
mov ah,4Ch
int 21h ; terminate with al=return code
sto endp
;---------------------------- int 16 d�tourn�e -----------------------------
int_16h_entry proc far
int16: push ax
push ds
push bp
push cx
pushf ; Push flags
cmp byte ptr ds:[drap],1 ; Je regarde si c'est fait.
jz loc_2
cmp ah,1 ; Sous- fonction 01
jne loc_2 ; Jump if not equal
mov ax,sp
mov bp,ds
mov cx,20 ; On pope 20 fois pour trouver
incr: pop ds ; le bon segment.
dec cx
jz s
cmp word ptr ds:[adr_ip],2274h ; Si ok on patche.
jnz incr ; Sinon on incr�mente.
mov byte ptr ds:[adr_ip],0ebh
mov ds,bp
mov byte ptr ds:[drap],1 ; On y revient plus.
s: mov sp,ax
loc_2: popf
pop cx
pop bp
pop ds
pop ax
jmp dword ptr cs:data_9
int_16h_entry endp
;------------ REDUCTION DE LA PLACE OCCUPEE PAR LE PROGRAMME COM ------------
init: mov ah,4ah
mov bx,offset fin ; Fin du programme en BX.
mov cl,4 ; Divis� par 4 pour avoir des paragraphes.
shr bx,cl
inc bx ; On en rajoute un par s�curit�.
int 21h ; Execution de la fonction 4Ah.
mov sp,offset fin ; on d�place la pile en "fin" car elle est
jmp loc_1 ; plac�e en FFFE dans un programme COM.
fin_init label near
;----------------------- PLACE RESERVEE POUR LA PILE ------------------------
dw (256-((fin_init-init) shr 1)) dup (?)
fin equ this byte ; ici le sommet de la pile, SP
seg_a ends
end start
|